package com.liangsui.mss.controller.doctor;

import cn.hutool.core.bean.BeanUtil;
import com.liangsui.mss.constants.AuthServerConstant;
import com.liangsui.mss.constants.Constants;
import com.liangsui.mss.domain.*;
import com.liangsui.mss.dto.PatientDto;
import com.liangsui.mss.dto.PatientFileDto;
import com.liangsui.mss.service.CareService;
import com.liangsui.mss.service.PatientService;
import com.liangsui.mss.utils.IdGeneratorSnowflake;
import com.liangsui.mss.vo.AjaxResult;
import com.liangsui.mss.vo.DataGridView;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * PatientController
 *
 * @author zhangjiawei
 * @email 1533167396@qq.com
 * @date 2022/12/7 16:46
 */
@RestController
@RequestMapping("doctor/patient")
public class PatientController {
    /**
     * @功能描述:患者信息和患者详细详细远程调用
     */
    @DubboReference
    private PatientService patientService;

    /**
     * @功能描述:调用就诊的患者病例详细远程调用
     */
    @DubboReference
    private CareService careService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * @功能描述:分页查询所有患者信息
     * @Description:使用sentinel替代hystrix--该接口演示用
     */
    @GetMapping("listPatientForPage")
    public AjaxResult listPatientForPage(PatientDto patientDto) {
        DataGridView dataGridView = this.patientService.listPatientForPage(patientDto);
        return AjaxResult.success("查询成功", dataGridView.getData(), dataGridView.getTotal());
    }

    /**
     * @功能描述:患者库信息导出
     * @Description:
     */
//	@GetMapping("getPatientAllExcel")
//	public AjaxResult getPatientAllExcel(PatientDto patientDto) {
//		try {
//			String fileName = "患者信息" + DateUtils.formatDate(new Date(), "yyyyMMdd") + ".xlsx";
//			DataGridView dataGridView = this.patientService.listPatientForPage(patientDto);
//			List<Patient> data = (List<Patient>) dataGridView.getData();
//			new ExportExcel("患者信息", Patient.class).setDataList(data).write(response, fileName, request).dispose();
//			return AjaxResult.success("导出成功");
//		} catch (Exception e) {
//			return AjaxResult.error("导出异常" + e.getMessage());
//		}
//	}


    /**
     * @功能描述:根据患者ID查询患者信息
     * @Description:
     */
    @GetMapping("getPatientById/{patientId}")
    public AjaxResult getPatientById(@PathVariable @NotNull(message = "患者ID不允许为空") String patientId) {
        Patient patient = this.patientService.getPatientById(patientId);
        return AjaxResult.success(patient);
    }

    /**
     * @功能描述:根据患者ID查询患者的档案信息
     * @Description:
     */
    @GetMapping("getPatientFileById/{patientId}")
    public AjaxResult getPatientFileById(@PathVariable @NotNull(message = "患者ID不允许为空") String patientId) {
        PatientFile patientFile = this.patientService.getPatientFileById(patientId);
        return AjaxResult.success(patientFile);
    }

    /**
     * 添加患者信息，小程序端
     * @param
     * @return
     */
    @PostMapping("register")
    public AjaxResult addPatient(@RequestParam(value = "username") String username,
                                 @RequestParam(value = "phone") String phone,
                                 @RequestParam(value = "id") String id,
                                 @RequestParam(value = "date") String date,
                                 @RequestParam(value = "sex") String sex,
                                 @RequestParam(value = "addr") String addr,
                                 @RequestParam(value = "code") String code
                                 ) {
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        String redisCode = opsForValue.get(AuthServerConstant.SMS_CODE_PREFIX + username);
        if (null == redisCode) {
            return AjaxResult.error("验证码已经过期,请重新获取");
        } else {
            String code1 = redisCode.split("_")[0];
            //进行比较，不考虑大小写
            if (!code1.equalsIgnoreCase(code)) {
                return AjaxResult.error("验证码错误");
            }
            redisTemplate.delete(AuthServerConstant.SMS_CODE_PREFIX + username);
            PatientDto patientDto = new PatientDto();
            patientDto.setAddress(addr);
            patientDto.setBirthday(date);
            patientDto.setIdCard(id);
            patientDto.setSex(sex);
            patientDto.setName(username);
            patientDto.setPhone(phone);
            patientDto.setPatientId(IdGeneratorSnowflake.generatorIdWithProfix(Constants.ID_PREFIX_HZ));
            Patient patient = patientService.addPatient(patientDto);
            return AjaxResult.success(patient);
        }
    }

    /**
     * 修改患者信息
     * @param username
     * @param phone
     * @param id
     * @param date
     * @param sex
     * @param addr
     * @return
     */
    @PutMapping("updatePatientInfoByPhone")
    public AjaxResult updatePatientInfoByPhone(@RequestParam(value = "username") String username,
                                                 @RequestParam(value = "phone") String phone,
                                                 @RequestParam(value = "id") String id,
                                                 @RequestParam(value = "date") String date,
                                                 @RequestParam(value = "sex") String sex,
                                                 @RequestParam(value = "addr") String addr
                                                ) {
        Patient patientInfo = patientService.getPatientByPhone(phone);
        if (username.equals(patientInfo.getName()) && id.equals(patientInfo.getIdCard()) && date.equals(patientInfo.getBirthday())
        && sex.equals(patientInfo.getSex()) && addr.equals(patientInfo.getAddress())) {
            return AjaxResult.error(400, "没有要修改的信息");
        }
        PatientDto patientDto = new PatientDto();
        patientDto.setAddress(addr);
        patientDto.setBirthday(date);
        patientDto.setIdCard(id);
        patientDto.setSex(sex);
        patientDto.setName(username);
        patientDto.setPhone(phone);
        Patient patient = patientService.updatePatientInfoByPhone(patientDto);
        return AjaxResult.success(patient);
    }

    /**
     * @功能描述:根据患者ID查询患者所有信息【基础，档案，病例】---已完成
     * @Description:
     */
    @GetMapping("getPatientAllMessageByPatientId/{patientId}")
    public AjaxResult getPatientAllMessageByPatientId(@PathVariable @NotNull(message = "患者ID不允许为空") String patientId) {
        // 根据患者ID 查询患者病例信息
        List<CareHistory> careHistories = this.careService.queryCareHistoryByPatientId(patientId);
        // 构造返回数据
        List<Map<String, Object>> res = new ArrayList<>();
        // 遍历开始
        for (CareHistory careHistory : careHistories) {
            // 将每一个 病例信息转换map
            Map<String, Object> map = BeanUtil.beanToMap(careHistory);
            // 1. 构造处方信息
            map.put("careOrders", Constants.EMPTY_LIST);
            // 1.1 构造组装 病例 和 处方信息
            List<Map<String, Object>> reCareOrders = new ArrayList<>();
            // 1.2 根据病例ID 查询处方信息
            List<CareOrder> careOrders = this.careService.queryCareOrdersByChId(careHistory.getChId());
            // 2. 根据处方ID 查询处方详细信息
            for (CareOrder careOrder : careOrders) {
                // 2.2 转换每一个处方对象 （json串）
                Map<String, Object> careOrderMap = BeanUtil.beanToMap(careOrder);
                // 2.3 根据处方ID 查询处方详细信息
                List<CareOrderItem> careOrderItems = this.careService.queryCareOrdersItemsByCoId(careOrder.getCoId(), null);
                // 2.4 将查询到的处方详细详细 注入到careOrderMap
                careOrderMap.put("careOrderItems", careOrderItems);
                // 3. 添加到集合当中
                reCareOrders.add(careOrderMap);
            }
            // 返回组装好的 病例  病例详情 处方  处方详情
            map.put("careOrders", reCareOrders);
            res.add(map);
        }
        // 遍历结束

        return AjaxResult.success(res);
    }

    @GetMapping("login")
    public AjaxResult patientLogin(@RequestParam(value = "username") String username,
                                @RequestParam(value = "password") String password,
                                   @RequestParam(value = "code") String code) {
        if (username == null || username.isEmpty() || password == null || password.isEmpty() || code == null
                || code.isEmpty()) {
            return AjaxResult.error(400, "手机号或密码不能为空");
        }
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        String redisCode = opsForValue.get(AuthServerConstant.SMS_CODE_PREFIX + username);
        if (null == redisCode) {
            return AjaxResult.error("验证码已经过期,请重新获取");
        } else {
            String code1 = redisCode.split("_")[0];
            //进行比较，不考虑大小写
            if (!code1.equalsIgnoreCase(code)) {
                return AjaxResult.error("验证码错误");
            }
            Patient patient = patientService.getPatientByUsername(username, password);
            if (patient != null) {
                redisTemplate.delete(AuthServerConstant.SMS_CODE_PREFIX + username);
                return AjaxResult.success(patient);
            } else {
                return AjaxResult.error(400, "用户不存在或密码错误");
            }
        }
    }

    @PutMapping("updatePassword")
    public AjaxResult updatePassword(@RequestParam(value = "username") String username,
                                   @RequestParam(value = "password") String password,
                                     @RequestParam(value = "code") String code) {
        if (username == null || username.isEmpty() || password == null || password.isEmpty() || code == null
                || code.isEmpty()) {
            return AjaxResult.error(400, "手机号或密码不能为空");
        }
        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        String redisCode = opsForValue.get(AuthServerConstant.SMS_CODE_PREFIX + username);
        if (null == redisCode) {
            return AjaxResult.error("验证码已经过期,请重新获取");
        } else {
            String code1 = redisCode.split("_")[0];
            //进行比较，不考虑大小写
            if (!code1.equalsIgnoreCase(code)) {
                return AjaxResult.error("验证码错误");
            }
            Patient patient = patientService.getPatientByUsername(username, password);
            if (patient != null) {
                return AjaxResult.error(400, "密码和原先密码一致");
            } else {
                redisTemplate.delete(AuthServerConstant.SMS_CODE_PREFIX + username);
                int i = patientService.updatePassword(username, password);
                if (i == 0) {
                    return AjaxResult.error();
                } else {
                    return AjaxResult.success();
                }
            }
        }
    }

    @PostMapping("addOrUpdatePatientFile")
    public AjaxResult addOrUpdatePatientFile(@RequestBody PatientFileDto patientFileDto) {
        String patientId = patientFileDto.getPatientId();
        PatientFile patientFileById = patientService.getPatientFileById(patientId);
        if (patientFileById != null) {
            if (patientFileById.getEmergencyContactName().equals(patientFileDto.getEmergencyContactName()) &&
                    patientFileById.getEmergencyContactPhone().equals(patientFileDto.getEmergencyContactPhone()) &&
                    patientFileById.getEmergencyContactRelation().equals(patientFileDto.getEmergencyContactRelation()) &&
                    patientFileById.getLeftEarHearing().equals(patientFileDto.getLeftEarHearing()) &&
                    patientFileById.getRightEarHearing().equals(patientFileDto.getRightEarHearing()) &&
                    patientFileById.getLeftVision().compareTo(patientFileDto.getLeftVision()) == 0 ? true : false &&
                    patientFileById.getRightVision().compareTo(patientFileDto.getRightVision()) == 0 ? true : false &&
                    patientFileById.getHeight().compareTo(patientFileDto.getHeight()) == 0 ? true : false &&
                    patientFileById.getWeight().compareTo(patientFileDto.getWeight()) == 0 ? true : false &&
                    patientFileById.getPersonalInfo().equals(patientFileDto.getPersonalInfo()) &&
                    patientFileById.getFamilyInfo().equals(patientFileDto.getFamilyInfo())) {
                return AjaxResult.error(400, "修改内容前后一致");
            } else {
                patientService.updatePatientFile(patientFileDto);
                return AjaxResult.success();
            }
        } else {
            patientService.addPatientFile(patientFileDto);
            return AjaxResult.success();
        }
    }
}
